﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.SqlClient;
using System.Data;

namespace CenyLetu
{
    /// <summary>
    /// Databázový komunikátor.
    /// </summary>
    class Db
    {
        /// <summary>
        /// Singleton - instance třídy.
        /// </summary>
        private static Db instance;
        /// <summary>
        /// Connection string do MSSQL.
        /// </summary>
        private string sqlConnectionString = @"Data Source=(local)\SQLEXPRESS; Database=PDS01; Integrated Security=Yes; Connect Timeout=30;";
        /// <summary>
        /// Instance spojení do DB.
        /// </summary>
        private SqlConnection spojeni;
        /// <summary>
        /// Instance transakce.
        /// </summary>
        private SqlTransaction transakce;

        /// <summary>
        /// Konstruktor.
        /// </summary>
        private Db()
        {
            spojeni = new SqlConnection(sqlConnectionString);
            spojeni.Open();
        }

        /// <summary>
        /// Vrací instanci třídy (singleton).
        /// </summary>
        /// <returns>Instance třídy.</returns>
        public static Db DejInstanci()
        {
            if (instance == null)
                instance = new Db();

            return instance;
        }

        /// <summary>
        /// Zahájí DB transakci.
        /// </summary>
        public void ZahajTranskaci()
        {

            if (transakce != null)
            {
                throw new InvalidOperationException("Transkace je již aktivní");
            }

            transakce = spojeni.BeginTransaction();
        }

        /// <summary>
        /// Provede commit transakce.
        /// </summary>
        public void Commit()
        {
            if (transakce == null)
            {
                throw new InvalidOperationException("Transkace není aktivní, nelze provést Commit");
            }

            transakce.Commit();
            transakce = null;
        }

        /// <summary>
        /// Provede rollback transakce.
        /// </summary>
        public void Rollback()
        {
            if (transakce == null)
            {
                throw new InvalidOperationException("Transkace není aktivní, nelze provést Rollback");
            }

            transakce.Rollback();
            transakce = null;

        }

        /// <summary>
        /// Provede příkaz (typ UPDATE/INSERT/DELETE) v databázi.
        /// </summary>
        /// <param name="prikaz">SQL příkazu.</param>
        /// <returns>True, pokud nenastala výjimka.</returns>
        public bool ProvedPrikaz(string prikaz) 
        {
            
            SqlCommand command = new SqlCommand(prikaz, spojeni);
            if (transakce != null)
                command.Transaction = transakce;

            try
            {
                command.ExecuteNonQuery();
            }
            catch (SqlException e)
            {
                Log.DejInstanci().ZapisUdalost("Nastala DB výjimka: " + e.Message);
                return false;
            }

            return true;
        }

        /// <summary>
        /// Provede čtení (SELECT) v databázi.
        /// </summary>
        /// <param name="prikaz">SQL příkazu.</param>
        /// <returns>DataTable s výsledkem příkazu.</returns>
        public DataTable ProvedCteni(string prikaz)
        {
            DataTable dataTable = new DataTable();

            try
            {
                SqlDataAdapter MyAdapter = new SqlDataAdapter();
                MyAdapter.SelectCommand = new SqlCommand(prikaz, spojeni);
                MyAdapter.Fill(dataTable);
            }
            catch (InvalidOperationException e)
            {
                Log.DejInstanci().ZapisUdalost("Nepodařilo se načíst data z DB: " + e.Message);
                return null;
            }

            return dataTable;
        }

    }
}
